package com.imooc.controller;


import com.alibaba.cloud.commons.lang.StringUtils;
import com.google.gson.Gson;
import com.imooc.base.BaseInfoProperties;
import com.imooc.bo.IndustryBO;
import com.imooc.mq.DelayConfig_Intustry;
import com.imooc.pojo.Industry;
import com.imooc.result.GraceJSONResult;
import com.imooc.service.IndustryService;
import com.imooc.utils.GsonUtils;
import com.imooc.utils.LocalDateUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 行业表 前端控制器
 * </p>
 *
 * @author liansen
 * @since 2023-03-28
 */
@RestController
@RequestMapping("/industry")
public class IndustryController extends BaseInfoProperties {

    @Autowired
    private IndustryService industryService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/app/initTopList")
    public GraceJSONResult initTopList(){
        String topList = redisTemplate.opsForValue().get(TOP_INDUSTRY_LIST);
        List<Industry> industries = new ArrayList<>();
        if(StringUtils.isNotBlank(topList)){
            //将从redis中获得的json字符串转成list
            industries = GsonUtils.stringToListAnother(topList, Industry.class);
            return GraceJSONResult.ok(industries);
        }else {
            industries = industryService.getTopList();
            String jsonString = new Gson().toJson(industries);
            redisTemplate.opsForValue().set(TOP_INDUSTRY_LIST, jsonString);
        }
        return GraceJSONResult.ok(industries);
    }

    @GetMapping("/app/getThirdListByTop/{topId}")
    public GraceJSONResult getThirdList(@PathVariable("topId") String topId){
        String thirdIndustryJsonStr = redisTemplate.opsForValue().get(THIRD_INDUSTRY_LIST + ":TopId:" + topId);
        List<Industry> thirdIndustries = new ArrayList<>();
        if(StringUtils.isNotBlank(thirdIndustryJsonStr)){
            thirdIndustries = GsonUtils.stringToList(thirdIndustryJsonStr, Industry.class);
        }else {
            thirdIndustries = industryService.getThirdList(topId);
//            String thirdStr = new Gson().toJson(thirdIndustries);
//            redisTemplate.opsForValue().set(THIRD_INDUSTRY_LIST + ":TopId:" + topId, thirdStr);

            //防止缓存穿透
            if(!CollectionUtils.isEmpty(thirdIndustries)){
                String thirdStr = new Gson().toJson(thirdIndustries);
                redisTemplate.opsForValue().set(THIRD_INDUSTRY_LIST + ":TopId:" + topId, thirdStr);
            }else {
                //设置过期时间10分钟
                redisTemplate.opsForValue().set(THIRD_INDUSTRY_LIST + ":TopId:" + topId, "[]", 10 * 60);
            }
        }
        return GraceJSONResult.ok(thirdIndustries);
    }

    //    ------------------------以上提供给app端使用----------------


    public void resetRedisIndustry(Industry industry){
        //删除一级节点数据
        if(industry.getLevel() == 1){
            List<Industry> industries = new ArrayList<>();
            redisTemplate.delete(TOP_INDUSTRY_LIST);
            industries = industryService.getTopList();
            String jsonString = new Gson().toJson(industries);
            redisTemplate.opsForValue().set(TOP_INDUSTRY_LIST, jsonString);
            //缓存双删
            try {
                Thread.sleep(300);
                redisTemplate.delete(TOP_INDUSTRY_LIST);
                redisTemplate.opsForValue().set(TOP_INDUSTRY_LIST, jsonString);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            List<Industry> thirdIndustries = new ArrayList<>();
            //通过三级节点数据的id找到对应的一级节点id
            String topIndustryId = getTopIndustryIdByThirdIndustryId(industry.getId());
            //删除三级节点数据
            redisTemplate.delete(THIRD_INDUSTRY_LIST + ":TopId:" + topIndustryId);
            thirdIndustries = industryService.getThirdList(topIndustryId);
            String thirdStr = new Gson().toJson(thirdIndustries);
            redisTemplate.opsForValue().set(THIRD_INDUSTRY_LIST + ":TopId:" + topIndustryId, thirdStr);
            //缓存双删
            try {
                Thread.sleep(300);
                redisTemplate.delete(THIRD_INDUSTRY_LIST + ":TopId:" + topIndustryId);
                redisTemplate.opsForValue().set(THIRD_INDUSTRY_LIST + ":TopId:" + topIndustryId, thirdStr);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }


    //    ------------------------以下提供给运营admin平台使用----------------
    @PostMapping("/createNode")
    public GraceJSONResult createNode(@RequestBody @Validated IndustryBO industryBO){

        String industryName = industryBO.getName();
        //查询行业名称存不存在
        boolean industryByName = industryService.getIndustryByName(industryName);
        if(industryByName){
            return GraceJSONResult.errorMsg("此行业已经存在");
        }
        Industry industry = new Industry();
        BeanUtils.copyProperties(industryBO, industry);
        industryService.save(industry);
        //将redis中的节点数据集合删除
//        resetRedisIndustry(industry);
        return GraceJSONResult.ok();
    }

    private String getTopIndustryIdByThirdIndustryId(String id) {
        return industryService.getTopIndustryIdByThirdIndustryId(id);
    }

    @GetMapping("/getTopList")
    public GraceJSONResult getTopList(){
        List<Industry> topList = industryService.getTopList();
        return GraceJSONResult.ok(topList);
    }

    @GetMapping("/children/{id}")
    public GraceJSONResult getChildrenIndustryList(@PathVariable("id") String id){
        List<Industry> topList = industryService.getChildrenIndustryList(id);
        return GraceJSONResult.ok(topList);
    }

    @PostMapping("/updateNode")
    public GraceJSONResult updateNode(@RequestBody Industry industry){
        industryService.updateById(industry);
        //将redis中的节点数据集合删除
//        resetRedisIndustry(industry);
        return GraceJSONResult.ok();
    }

    @DeleteMapping("/deleteNode/{id}")
    public GraceJSONResult deleteNode(@PathVariable("id") String id){
        Industry industry = industryService.getById(id);
        //如果要删除的节点下面还有子节点，就不能删除
        Long counts = industryService.getChildrenCounts(id);
        if(counts > 0){
            return GraceJSONResult.errorMsg("该节点下有子节点, 无法删除");
        }
        //将redis中的节点数据集合删除
//        resetRedisIndustry(industry);
        industryService.removeById(industry);
        return GraceJSONResult.ok();
    }


    /*
        之前是运维端每次对行业进行增删改，都得同步删除redis中的数据;
        现在利用缓存的弱一致性，用延迟队列，在运维端对行业数据进行增删改后,
        点击刷新缓存按钮, 在凌晨3点再刷新redis的数据;
     */
    @GetMapping("/refreshIndustry")
    public GraceJSONResult refreshIndustry(){

        //凌晨三点
        LocalDateTime futureTime = LocalDateUtils.
                parseLocalDateTime(LocalDateUtils.getTomorrow() + " 03:00:00", LocalDateUtils.DATETIME_PATTERN);
        //计算当前时间到凌晨三点的时间差
        Long times = LocalDateUtils.getChronoUnitBetween(LocalDateTime.now(), futureTime, ChronoUnit.MILLIS, true);

//        int delayTimes = times.intValue();

        //消息发送进入队列后
        int delayTimes = 10 * 1000;

        //消息发送之后，消费端10秒之后才能收到并消费
        rabbitTemplate.convertAndSend(DelayConfig_Intustry.EXCHANGE_DELAY_REFRESH,
                                        DelayConfig_Intustry.DELAY_REFRESH_INDUSTRY,
                                        "123456",
                                        DelayConfig_Intustry.setDelayTimes(delayTimes)
                                      );
        return GraceJSONResult.ok("111");
    }

}


